#pragma once
#include <memory>
#include <queue>
#include "mutex.hpp"
#include <pthread.h>

// // 使用模板+继承+多态
// // 每个有模板的地方都要加 <>!!!!!
// // 继承方式那要加
// // 指名模板类中的类型时需要typename


template<typename T>
class basic_buf
{
public:
    using ptr = std::shared_ptr<basic_buf<T>>;
    basic_buf()
    {
        pthread_cond_init(&_cond_con,nullptr);
        pthread_cond_init(&_cond_pro,nullptr);
        pthread_mutex_init(&_mutex_pro_con,nullptr);
        pthread_mutex_init(&_mutex_pro,nullptr);
        pthread_mutex_init(&_mutex_con,nullptr);
    }
    //普通缓冲区的接口
    virtual void push(const T& val) = 0;
    virtual void pop(T* val) = 0;
    // 为双缓冲区设计的接口
    virtual void push(const T& val,size_t sz) = 0;
    virtual void pop(T* val,size_t sz) = 0;
    virtual bool empty() = 0;
    virtual bool full() = 0;

    virtual ~basic_buf()
    {
        pthread_cond_destroy(&_cond_con);
        pthread_cond_destroy(&_cond_pro);
        pthread_mutex_destroy(&_mutex_pro_con);
        pthread_mutex_destroy(&_mutex_pro);
        pthread_mutex_destroy(&_mutex_con);
    }
    // 私有继承派生类是看不到的！！
    // 需要保护继承
protected:
    pthread_mutex_t _mutex_pro_con;
    pthread_cond_t _cond_con; // 消费者的条件变量
    pthread_cond_t _cond_pro; // 生产者的条件变量
    pthread_mutex_t _mutex_pro;
    pthread_mutex_t _mutex_con;

};




